# coding:utf-8
"""
python 使用abc实现类似于java的接口模式(抽象类),子类必须实现接口的所有方法
six: 兼容py2和py3
"""

import abc
import six


@six.add_metaclass(abc.ABCMeta)
class Base(object):
    @abc.abstractmethod
    def people(self):
        """
        an abstract method need to be implemented
        :return:
        """
        pass

    @abc.abstractmethod
    def car(self):
        """
        an abstract method need to be implemented
        :return:
        """
        pass


class RegisteredImplementation(object):
    def house(self):
        print('somebody i used to know')


# 实现接口方法
class ImplementBase(Base):
    def people(self):
        print("this is a person")

    def car(self):
        print('this is a car')


if __name__ == '__main__':
    # 注册虚拟子类
    Base.register(RegisteredImplementation)
    # abc.ABCMeta.register(Base, RegisteredImplementation)
    for sc in Base.__subclasses__():
        # 没任何结果输出,说明虚拟子类不是真正的子类
        print("subclass of Base: {}".format(sc.__name__))

    # 均打印True,说明虚拟子类影响这两个判断方法
    print("issubclass: {}".format(issubclass(RegisteredImplementation, Base)))
    print("isinstance: {}".format(isinstance(RegisteredImplementation(), Base)))

    imp = RegisteredImplementation()
    # 调用自身的方法ok
    print(imp.house())
    # AttributeError: 'RegisteredImplementation' object has no attribute 'car'
    # print(imp.car())

    real = ImplementBase() # 实例化会打印一个None , why ???
    print(real.people())
    print(real.car())
    # print(real.house()) # AttributeError: 'ImplementBase' object has no attribute 'house'
